package com.github.lh

import java.security.Key
import java.security.MessageDigest
import java.security.PrivateKey
import java.security.Signature
import java.util.*
import java.security.PublicKey




fun applySha256(input: String): String =
        with(MessageDigest.getInstance("SHA-256")) {
            digest(input.toByteArray(Charsets.UTF_8))
                    .joinToString(separator = "") {
                        val hex = Integer.toHexString(0xff and it.toInt())
                        if (hex.length == 1) "0$hex" else hex
                    }
        }


fun applyECDSASig(privateKey: PrivateKey, input: String): ByteArray =
        with(Signature.getInstance("ECDSA", "BC")) {
            initSign(privateKey)
            update(input.toByteArray(Charsets.UTF_8))
            sign()
        }

fun verifyECDSASig(publicKey: PublicKey, data: String, signature: ByteArray): Boolean =
        with(Signature.getInstance("ECDSA", "BC")) {
            initVerify(publicKey)
            update(data.toByteArray(Charsets.UTF_8))
            verify(signature)
        }

fun getDificultyString(difficulty: Int): String =
        String(CharArray(difficulty)).replace('\u0000', '0')


fun getStringFromKey(key: Key): String =
        Base64.getEncoder().encodeToString(key.encoded)


fun getMerkleRoot(transactions: ArrayList<Transaction>): String {
    var count = transactions.size

    var previousTreeLayer: MutableList<String> = transactions.mapTo(ArrayList()) { it.transactionId }
    var treeLayer: MutableList<String> = previousTreeLayer

    while (count > 1) {
        treeLayer = ArrayList()
        var i = 1
        while (i < previousTreeLayer.size) {
            treeLayer.add(applySha256(previousTreeLayer[i - 1] + previousTreeLayer[i]))
            i += 2
        }
        count = treeLayer.size
        previousTreeLayer = treeLayer
    }
    return if (treeLayer.size == 1) treeLayer.first() else ""

}
